home *** CD-ROM | disk | FTP | other *** search
/ APDL Eductation Resources / APDL Eductation Resources.iso / programs / graphics / gif2rpc / source / 16bpp_66bi / c / jjn < prev    next >
Encoding:
Text File  |  1995-10-16  |  4.5 KB  |  127 lines

  1. /* jjn.c
  2.  * AUTHOR:      Cy Booker, cy@cheepnis.demon.co.uk
  3.  * LICENSE:     FreeWare, Copyright (c) 1995 Cy Booker
  4.  *
  5.  * filter:              *  7  5
  6.  *                3  5  7  5  3
  7.  *                1  3  5  3  1         (1/48)
  8.  */
  9.  
  10. #include "internal.h"
  11.  
  12.  
  13. #include <assert.h>
  14. #include <string.h>             /* memset() */
  15. #include <stdlib.h>             /* calloc() */
  16.  
  17. #include "OS:hourglass.h"
  18. #include "OS:macros.h"
  19.  
  20.  
  21.  
  22. /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  23.  */
  24.  
  25. extern bool process_gif_16bpp_jarvis_judice_ninke_66bit(
  26.                 const process_gif       *p) {
  27.   byte                  *rove;
  28.   int                   width, height;
  29.   int                   x, y;
  30.   const os_colour       *palette;
  31.   int                   line_length;
  32.   int                   *buffer, *this_row, *next_row, *botm_row;
  33.   int                   buffer_width;
  34.   int                   r, g, b;
  35.   int                   or, og, ob;
  36.   int                   t;
  37.   int                   er, eg, eb;
  38.  
  39.   assert(p);
  40.   assert(p->pixel_width > 0);
  41.   assert(p->pixel_height > 0);
  42.   assert(p->in_palette.colours);
  43.  
  44.  
  45.   /*
  46.    * jarvis_judice_ninke requires storing error info for two pixels to right and two pixels to left
  47.    * so we will just allocate two extra columns for each row and not do any edge checks
  48.    * each entry is stored as {r*SCALE, g*SCALE, b*SCALE}
  49.    */
  50.   buffer_width = (2 + p->pixel_width + 2) * 3;
  51.   buffer = calloc(1, sizeof(*buffer) * (buffer_width * 3));
  52.   if (!buffer) {
  53.     /*
  54.      * oh dear
  55.      */
  56.     return TRUE;
  57.   }
  58.  
  59.   initialise_scaling_tables();
  60.  
  61.   /*
  62.    * not we pre-load values from the process_gif array
  63.    * because it considerably helps the compiler produce better code
  64.    */
  65.   rove = p->buffer;
  66.   width = p->pixel_width;
  67.   height = p->pixel_height;
  68.   palette = p->in_palette.colours;
  69.   line_length = p->line_length;
  70.   for (y= height; (y > 0); y--) {
  71.     if ((y & 7) == 0) {
  72.       xhourglass_percentage((y * 100) / height);
  73.     }
  74.     this_row = buffer + (buffer_width * ((y + 3) % 3)) + 2*3;
  75.     next_row = buffer + (buffer_width * ((y + 2) % 3)) + 2*3;
  76.     botm_row = buffer + (buffer_width * ((y + 1) % 3)) + 2*3;
  77.     /* bottom row has no errors */
  78.     memset(botm_row, 0, sizeof(*botm_row) * (buffer_width - 2*3));
  79.     /*
  80.      * note that just because we are actually scanning/outputting right to left
  81.      * doesn't matter as far as the filter is concerned
  82.      * although it might help if we could ``snake''
  83.      */
  84.     for (x= width - 1; (x >= 0); x--) {
  85.       INPUT;
  86.       r += *this_row++;                                 /* add in errors from all rows */
  87.       g += *this_row++;
  88.       b += *this_row++;
  89.       PROCESS;
  90.       r -= or;  g -= og; b-= ob;                        /* error */
  91.       er = (r * 7) / 48; eg = (g * 7) / 48; eb = (b * 7) / 48;
  92.       this_row[ 0] += er; this_row[ 1] += eg; this_row[ 2] += eb;       /* this[ 1] += 7/48 */
  93.       next_row[ 0] += er; next_row[ 1] += eg; next_row[ 2] += eb;       /* next[ 0] += 7/48 */
  94.       or = r - (2*er); og = g - (2*eg); ob = b - (2*eb);                /* remainder of r error left */
  95.  
  96.       er = (r * 5) / 48; eg = (g * 5) / 48; eb = (b * 5) / 48;
  97.       this_row[ 3] += er; this_row[ 4] += eg; this_row[ 5] += eb;       /* this[ 2] += 5/48 */
  98.       next_row[ 3] += er; next_row[ 4] += eg; next_row[ 5] += eb;       /* next[ 1] += 5/48 */
  99.       next_row[-3] += er; next_row[-2] += eg; next_row[-1] += eb;       /* next[-1] += 5/48 */
  100.       botm_row[ 0] += er; botm_row[ 1] += eg; botm_row[ 2] += eb;       /* botm[ 0] += 5/48 */
  101.       or -= 4 * er; og -= 4 * eg; ob -= 4 * eb;
  102.  
  103.       er = (r * 3) / 48; eg = (g * 3) / 48; eb = (b * 3) / 48;
  104.       next_row[ 6] += er; next_row[ 7] += eg; next_row[ 8] += eb;       /* next[ 2] += 3/48 */
  105.       next_row[-6] += er; next_row[-5] += eg; next_row[-4] += eb;       /* next[-2] += 3/48 */
  106.       botm_row[ 3] += er; botm_row[ 4] += eg; botm_row[ 5] += eb;       /* botm[ 1] += 3/48 */
  107.       botm_row[-3] += er; botm_row[-2] += eg; botm_row[-1] += eb;       /* botm[-1] += 3/48 */
  108.       or -= 4 * er; og -= 4 * eg; ob -= 4 * eb;
  109.  
  110.       er = (r * 1) / 48; eg = (g * 1) / 48; eb = (b * 1) / 48;
  111.       botm_row[-6] += er; botm_row[-5] += eg; botm_row[-4] += eb;       /* botm[-2] += 1/48 */
  112.  
  113.       or -= er; og -= eg; ob -= eb;
  114.       botm_row[ 6] += or;  botm_row[ 7] += og;  botm_row[ 8] += ob;     /* botm[+2] += 1/48 */
  115.  
  116.       next_row += 3;                                    /* adjust next_row pointer */
  117.       botm_row += 3;                                    /* adjust botm_row pointer */
  118.     }
  119.     rove += line_length;
  120.   }
  121.   free(buffer);
  122.   return FALSE;
  123. }
  124.  
  125.  
  126.  
  127.